#include "CLink/Router/ErrorHandler.h"
#include "CLink/Utils/ResponseUtils.h"
#include "CLink/error/Error.h"

namespace CLink
{
namespace Router
{

ErrorHandler::ErrorHandler(ErrorHandlerFunction handler)
    : m_handler(handler)
{
}

bool ErrorHandler::handle(RequestContext & /*context*/)
{
    // 错误处理器不应该直接处理请求
    // 它应该通过handleError方法被调用
    return false;
}

bool ErrorHandler::matches(const RequestContext & /*context*/) const
{
    // 错误处理器不参与路由匹配
    return false;
}

int ErrorHandler::getPriority() const
{
    // 返回最低优先级
    return std::numeric_limits<int>::min();
}

ErrorHandler &ErrorHandler::setHandler(ErrorHandlerFunction handler)
{
    m_handler = handler;
    return *this;
}

void ErrorHandler::handleError(RequestContext &context,
                                const CLink::Error::CLinkException &error)
{
    if (m_handler)
    {
        // 使用自定义错误处理函数
        m_handler(context, error);
    }
    else
    {
        // 使用默认错误处理函数
        defaultErrorHandler(context, error);
    }
}

void ErrorHandler::defaultErrorHandler(RequestContext &context,
                                        const CLink::Error::CLinkException &error)
{
    // 根据错误代码设置HTTP状态码
    int statusCode = 500; // 默认为内部服务器错误
    std::string statusMessage = "Internal Server Error";

    switch (error.getCode())
    {
    case Error::ErrorCode::DATA_NOT_FOUND:
        statusCode = Poco::Net::HTTPResponse::HTTP_NOT_FOUND;
        statusMessage = "Not Found";
        break;
    case Error::ErrorCode::UNAUTHORIZED:
        statusCode = Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED;
        statusMessage = "Unauthorized";
        break;
    case Error::ErrorCode::AUTHENTICATION_FAILED:
        statusCode = Poco::Net::HTTPResponse::HTTP_FORBIDDEN;
        statusMessage = "Forbidden";
        break;
    case Error::ErrorCode::INVALID_ARGUMENT: // 合并BAD_REQUEST和INVALID_PARAMETER
        statusCode = Poco::Net::HTTPResponse::HTTP_BAD_REQUEST;
        statusMessage = "Bad Request";
        break;
    case Error::ErrorCode::DATA_ALREADY_EXISTS:
        statusCode = Poco::Net::HTTPResponse::HTTP_CONFLICT;
        statusMessage = "Conflict";
        break;
    case Error::ErrorCode::INTERNAL_ERROR:
    default:
        statusCode = Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR;
        statusMessage = "Internal Server Error";
        break;
    }

    // 创建错误响应
    CLink::HttpResponseUtils::sendErrorJson(context.response,
                                            statusCode,
                                            statusMessage,
                                            error.getMessage());
}

} // namespace Router
} // namespace CLink